package com.google.code.p.mariosimulator;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.hardware.SensorListener;
import android.hardware.SensorManager;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.Bundle;
import android.os.PowerManager;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.GestureDetector;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.GestureDetector.OnGestureListener;
import android.view.MenuItem.OnMenuItemClickListener;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class MarioSimulator extends Activity implements SensorListener
{
  private SensorManager mSensorManager;
  private AudioManager audioManager;
  private boolean isTouch = false;
  private MediaPlayer themeSong;
  private VersionChecker versionChecker = null;
  private boolean themePlaying = false;
  private PowerManager.WakeLock mWakeLock;
  private boolean mWakeLockLocked = false;
  private int coinCount = 0;
  private float minVelocity = 7f;
  private TextView coinCountTxt;
  private boolean mute = true;

  private GestureDetector gd;
  
  
  private static final int PREFERENCE_ID = Menu.FIRST;
  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
      
      menu.add(0, PREFERENCE_ID, 0, "Settings").setIcon(R.drawable.settings).setOnMenuItemClickListener(new OnMenuItemClickListener(){

          @Override
          public boolean onMenuItemClick(MenuItem item) {
              Intent launchPreferencesIntent = new Intent(MarioSimulator.this, Preferences.class);
              
              // Make it a subactivity so we know when it returns
              startActivityForResult(launchPreferencesIntent, 1);
              return true;
          }
          
      });
      return true;
  }
  
    /** Called when the activity is first created. */
  @Override
  protected void onCreate(Bundle savedInstanceState) {
      // Be sure to call the super class.
      super.onCreate(savedInstanceState);
      PreferenceManager.setDefaultValues(this, R.xml.preferences, false);
      
      setContentView(R.layout.main);
      try {
        this.versionChecker = new VersionChecker(this);
        versionChecker.checkVersionAvailable();
    } catch (Exception e) {
        Log.e(MarioSimulator.class.toString(), e.getMessage(), e); //ignore version check error
    }
      coinCountTxt = (TextView) findViewById(R.id.coin_count);
      final Button button = (Button) findViewById(R.id.play);
      button.setOnClickListener(new OnClickListener(){

        @Override
        public void onClick(View v) {
          if(themePlaying){
            themePlaying = false;
            themeSong.pause();
            
            button.setText("Play theme song");
          }else{
            themePlaying = true;
            themeSong.start();
            button.setText("Pause theme song");
          }
        }
        
      });
      mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
      audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
      themeSong = MediaPlayer.create(this, R.raw.sm3_theme);
      themeSong.setLooping(true);
      SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this);
      mute = settings.getBoolean("mute", true);
      
      if(!mute){
          int volume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
          playSoundEffect(R.raw.sm64_memario, volume);
      }
      
      PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
      //mWakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK
      mWakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK
                      | PowerManager.ACQUIRE_CAUSES_WAKEUP
                      | PowerManager.ON_AFTER_RELEASE,
                      "Flashlight");
      

      
       gd = new GestureDetector(new OnGestureListener(){

        @Override
        public boolean onDown(MotionEvent e) {
          return false;
        }

        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2,
            float velocityX, float velocityY) {
          return false;
        }

        @Override
        public void onLongPress(MotionEvent e) {
        }

        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2,
            float distanceX, float distanceY) {
          return false;
        }

        @Override
        public void onShowPress(MotionEvent e) {
          // TODO Auto-generated method stub
          
        }

        @Override
        public boolean onSingleTapUp(MotionEvent e) {
          int volume = audioManager.getStreamVolume(AudioManager.STREAM_RING);
          playSoundEffect(R.raw.smb3_fireball, volume);
          return true;
        }
        
      });
  }

  @Override
  public boolean onTouchEvent(MotionEvent event) {
    if(event.getAction() == MotionEvent.ACTION_DOWN){
      isTouch = true;
    }else if(event.getAction() == MotionEvent.ACTION_UP){
      isTouch = false;
    }
    return gd.onTouchEvent(event);
  }
  
  @Override
  protected void onResume() {
      super.onResume();

      //get the user preferences
      SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this);
      String sensitivity = settings.getString("sensitivity", "Realistic");
      mute = settings.getBoolean("mute", true);
      if("Lazy".equalsIgnoreCase(sensitivity)){ 
          minVelocity = 4f;
      }else if("Realistic".equalsIgnoreCase(sensitivity)){
          minVelocity = 7f;
      }else if("Work-out".equalsIgnoreCase(sensitivity)){
          minVelocity = 15f;
      }
      
      coinCount = 0;
      state = State.NORMAL;
      wakeLock();
      isTouch = false;
      mSensorManager.registerListener(this, 
              SensorManager.SENSOR_ACCELEROMETER,
              SensorManager.SENSOR_DELAY_GAME   );
  }
  
  
  private void wakeLock() {
    if (!mWakeLockLocked) {
      Log.d(MarioSimulator.class.toString(), "Wake lock");
            mWakeLock.acquire();
            mWakeLockLocked = true;
    }
  }
  
  private void wakeUnlock() {
    if (mWakeLockLocked) {
      Log.d(MarioSimulator.class.toString(), "Wake unlock");
            mWakeLock.release();
            mWakeLockLocked = false;
    }
  }
  
  @Override
  protected void onStop() {
      mSensorManager.unregisterListener(this);
      super.onStop();
  }

  @Override
  public void onAccuracyChanged(int sensor, int accuracy) {
    // TODO Auto-generated method stub
    
  }

  @Override
  protected void onPause() {
    wakeUnlock();
    super.onPause();
  }
  
  
  private static enum State{
    NORMAL, IN_AIR
  }
  
  private State state = State.NORMAL;
  
  @Override
  public void onSensorChanged(int sensor, float[] values) {
    synchronized (this) {
        
      if(values[4]>minVelocity && state != State.IN_AIR){
          Log.d(MarioSimulator.class.toString(), "jump");
        state = State.IN_AIR;
        int volume = audioManager.getStreamVolume(AudioManager.STREAM_RING);
        if(isTouch){
          coinCountTxt.setText(String.valueOf(++coinCount));
          if(coinCount == 100){
            coinCount = 0;
            coinCountTxt.setText("0");
            playSoundEffect(R.raw.smb3_1up, volume);
            return;
          }
        }
        playSoundEffect(isTouch? R.raw.smb3_coin : R.raw.smb3_jump, volume);
        
      }else if(values[4] < 0f && state == State.IN_AIR){ //falling
          Log.d(MarioSimulator.class.toString(), "back to ground");
        state = State.NORMAL;
      }
    }
  }
  @Override
  protected void onDestroy() {
    if(themeSong != null){
      themeSong.stop();
      themeSong.release();
    }
    int volume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
    playSoundEffect(R.raw.smb3_mariodie, volume);
    super.onDestroy();
  }
  

  private void playSoundEffect(int resId, int volume){
//      Log.d("-------", "sound effect fired");
      MediaPlayer mp = MediaPlayer.create(this, resId);
      mp.setVolume(volume, volume);
      mp.setOnCompletionListener(new OnCompletionListener(){

        @Override
        public void onCompletion(MediaPlayer mp) {
          mp.release();
        }
        
      });
      mp.start();
  }

}
